package com.jolink.omiis.wechat.token;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonObject;
import com.jolink.omiis.wechat.api.impl.WeChatApiBaseService;
import com.jolink.omiis.wechat.keys.IPreferences;
import com.jolink.omiis.wechat.redis.IRedisProcessor;
import com.jolink.omiis.wechat.util.DateUtil;
import com.jolink.omiis.wechat.util.GsonUtil;

/**
 * 刷新公众号 AuthorizerAccessToken
 * 
 * @author WangYanqing
 *
 */
/**
 * @author WangYanqing
 *
 */
public class AuthorizerAccessTokenService extends WeChatApiBaseService implements IAuthorizerAccessTokenService {

	private static Logger logger = LoggerFactory.getLogger(AuthorizerAccessTokenService.class);
	private String baseUri = "https://api.weixin.qq.com/cgi-bin/component/api_authorizer_token";

	public AuthorizerAccessTokenService() {
	}

	/**
	 * 2016-20-12 by wangyq REDIS-CLUSTER
	 * 模式，不支持keys操作，需将keys存放到set中，通过set查找具体key值
	 */
	@Override
	public void refresh() {
		long t1 = System.currentTimeMillis();
		logger.info("开始刷新微信公众号AuthorizerAccessToken......");
		IRedisProcessor redis = getContext().getServiceUtil().getRedisProcessor();
		String[] companyArrays = null;
		try {
			Set<String> companySet = redis.smembers(IPreferences.COMPANY_SET);
			companyArrays = (String[]) companySet.toArray(new String[] {});
			logger.info("本次刷新的微信公众号列表：{}。", Arrays.toString(companyArrays));
		} catch (Exception e1) {
			logger.error("获取微信公众号信息失败：" + e1.getMessage(), e1);
			return;
		}

		Map<String, String> componentInfo = getContext().getCompentInfo();
		logger.error("服务平台信息：{}。", componentInfo);
		String component_access_token = componentInfo.get("component_access_token");
		String component_appid = componentInfo.get("app_id");
		for (String companyId : companyArrays) {
			long t11 = System.currentTimeMillis();
			logger.info("开始刷新微信公众号：{}，的AuthorizerAccessToken：", companyId);
			Map<String, String> companyMap = null;
			try {
				companyMap = redis.hgetall(companyId);
				logger.info("微信公众号：{}，基本信息：{}。", companyId, companyMap);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
			String company_app_id = companyMap.get(IPreferences.COMPANY_APP_ID);
			String access_token_update_timestamp = companyMap.get("access_token_update_timestamp");
			String authorizer_refresh_token = companyMap.get("authorizer_refresh_token");
			String authorizer_access_token = companyMap.get("authorizer_access_token");
			if (StringUtils.isEmpty(access_token_update_timestamp)) {
				// logger.error("刷新公众号信息异常，公众号：{}，跳过，忽略该公众号。", companyId);
				logger.warn("公众号：{}刷新时间戳记录不存在，可能是第一次授权。", companyId);
				access_token_update_timestamp = String.valueOf(0);
				// continue;
			}
			long last_update_timestamp = Long.parseLong(access_token_update_timestamp);
			long current_time = System.currentTimeMillis();
			long diff = current_time - last_update_timestamp;
			logger.info("微信公众号：{}，上次更新时间：{}，authorizer_refresh_token：{}，authorizer_access_token：{}，已使用时间：{}。",
					companyId, access_token_update_timestamp, authorizer_refresh_token, authorizer_access_token, diff);

			long min = 100 * 60 * 1000;// 6000000
			// if (diff <= 6000) {
			// logger.info("公众号：{}更新时间未到阀值，本次不进行刷新。", companyId);
			// continue;
			// }

			if (diff <= min) {
				logger.info("微信公众号：{}刷新Token未到阀值，本次跳过。", companyId);
				continue;
			}
			logger.info("向腾讯服务器发送申请公众号：{}的AuthorizerAccessToken请求：", companyId);
			Map<String, String> reqParams = new HashMap<>();
			reqParams.put("component_access_token", component_access_token);
			JsonObject postData = new JsonObject();
			postData.addProperty("component_appid", component_appid);
			postData.addProperty("authorizer_appid", company_app_id);
			postData.addProperty("authorizer_refresh_token", authorizer_refresh_token);
			String httpEntity = GsonUtil.jsonElement2Json(postData);
			logger.info("申请微信公众号：{}的AuthorizerAccessToken请求信息：{}。", companyId, httpEntity);
			String result = (String) executePost(baseUri, reqParams, httpEntity);
			Map<String, String> resultJson = GsonUtil.str2Map(result);
			logger.info("腾讯服务器返回结果：{}，str2Map：{}。", result, resultJson);
			if (resultJson.containsKey("errcode")) {
				logger.info("微信公众号：{}，申请AuthorizerAccessToken失败，微信公众号ID：{}，异常信息：{}。", companyId, resultJson);
				continue;
			}
			resultJson.put("access_token_update_timestamp", String.valueOf(System.currentTimeMillis()));
			resultJson.put("access_token_update_time", DateUtil.getCurrentDate());
			try {
				redis.hmset(companyId, resultJson);
				getContext().setCompanyInfo(IPreferences.COMPANY_REDIS_PREFIX + "_" + company_app_id, resultJson);
			} catch (Exception e) {
				logger.error(e.getMessage(), e);
			}
			long t21 = System.currentTimeMillis();
			logger.info("申请微信公众号：{}的AuthorizerAccessToken完成，耗时{}毫秒。", companyId, (t21 - t11));
		}
		long t2 = System.currentTimeMillis();
		logger.info("刷新微信公众号AuthorizerAccessToken完成，耗时：{}毫秒。", (t2 - t1));
	}

	@Override
	public void initialize() {

	}
}
